﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace SmartLib.Dal.Sql
{
    /// <summary>
    /// DataReader扩展方法，支持将DataReader转化为实体对象
    /// </summary>
    public static class DataReaderExtensions
    {
        /// <summary>
        /// 转化为实体对象集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="reader"></param>
        /// <returns></returns>
        public static List<T> ToEntities<T>(this IDataReader reader)
        {
            return ToEntities<T>(reader, string.Empty);
        }

        /// <summary>
        /// 转化为实体对象集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="reader"></param>
        /// <param name="prefix">前缀</param>
        /// <returns></returns>
        public static List<T> ToEntities<T>(this IDataReader reader, string prefix)
        {
            List<T> lst = new List<T>();

            SmartLib.Reflection.TypeReflection typeReflection =
               SmartLib.Reflection.TypeReflectionCache.FetchTypeReflection(typeof(T));

            while (reader.Read())
            {
                object instance = typeReflection.NewInstance();

                for (var i = 0; i < reader.FieldCount; i++)
                {
                    var name = reader.GetName(i);
                    if (!string.IsNullOrEmpty(prefix))
                    {
                        name = name.Substring(prefix.Length);
                    }

                    SmartLib.Reflection.PropertyReflection property = typeReflection[name];
                    if (property != null && !property.IgnoreSelect)
                    {
                        property.SetValue(instance, reader.GetValue(i));
                    }
                }

                lst.Add((T)instance);
            }

            return lst;
        }

        /// <summary>
        /// 转化为单个实体对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="reader"></param>
        /// <returns></returns>
        public static T ToEntity<T>(this IDataReader reader)
        {
            return ToEntity<T>(reader, string.Empty);
        }

        /// <summary>
        /// 转化为单个实体对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="reader"></param>
        /// <param name="prefix">前缀</param>
        /// <returns></returns>
        public static T ToEntity<T>(this IDataReader reader, string prefix)
        {
            SmartLib.Reflection.TypeReflection typeReflection = 
                SmartLib.Reflection.TypeReflectionCache.FetchTypeReflection(typeof(T));

            object instance = null;

            if (reader.Read())
            {
                instance = typeReflection.NewInstance();

                for (var i = 0; i < reader.FieldCount; i++)
                {
                    var name = reader.GetName(i);
                    if (!string.IsNullOrEmpty(prefix))
                    {
                        name = name.Substring(prefix.Length);
                    }

                    SmartLib.Reflection.PropertyReflection property = typeReflection[name];
                    if (property != null && !property.IgnoreSelect)
                    {
                        property.SetValue(instance, reader.GetValue(i));
                    }
                }
            }

            return (T)instance;
        }
    }
}
